package com.bookocean.application.service;

import com.bookocean.controller.dto.BadgeDto;
import com.bookocean.infrastructure.persistence.mapper.BadgeDefinitionMapper;
import com.bookocean.infrastructure.persistence.mapper.UserBadgeMapper;
import com.bookocean.infrastructure.persistence.po.BadgeDefinitionPO;
import com.bookocean.infrastructure.persistence.po.UserBadgePO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 徽章应用服务
 * 
 * @author BookOcean
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BadgeApplicationService {

    private final BadgeDefinitionMapper badgeDefinitionMapper;
    private final UserBadgeMapper userBadgeMapper;

    /**
     * 获取所有徽章定义
     * 
     * @return 徽章定义列表
     */
    public List<BadgeDto> getAllBadges() {
        log.info("获取所有徽章定义");
        
        List<BadgeDefinitionPO> badgeDefinitions = badgeDefinitionMapper.selectActiveBadges();
        return convertToBadgeDtos(badgeDefinitions, null);
    }

    /**
     * 根据分类获取徽章定义
     * 
     * @param category 徽章分类
     * @return 徽章定义列表
     */
    public List<BadgeDto> getBadgesByCategory(String category) {
        log.info("根据分类获取徽章定义，category: {}", category);
        
        List<BadgeDefinitionPO> badgeDefinitions = badgeDefinitionMapper.selectBadgesByCategory(category);
        return convertToBadgeDtos(badgeDefinitions, null);
    }

    /**
     * 获取用户徽章列表
     * 
     * @param userId 用户ID
     * @return 徽章列表
     */
    public List<BadgeDto> getUserBadges(Long userId) {
        log.info("获取用户徽章列表，userId: {}", userId);
        
        // 获取所有徽章定义
        List<BadgeDefinitionPO> allBadges = badgeDefinitionMapper.selectActiveBadges();
        
        // 获取用户已获得的徽章
        List<UserBadgePO> userBadges = userBadgeMapper.selectUserBadges(userId);
        Map<Long, UserBadgePO> userBadgeMap = userBadges.stream()
                .collect(Collectors.toMap(UserBadgePO::getBadgeId, badge -> badge));
        
        return convertToBadgeDtos(allBadges, userBadgeMap);
    }

    /**
     * 获取徽章详情
     * 
     * @param badgeId 徽章ID
     * @param userId 用户ID（可选，用于查询用户是否已获得）
     * @return 徽章详情
     */
    public BadgeDto getBadgeDetail(Long badgeId, Long userId) {
        log.info("获取徽章详情，badgeId: {}, userId: {}", badgeId, userId);
        
        BadgeDefinitionPO badgeDefinition = badgeDefinitionMapper.selectById(badgeId);
        if (badgeDefinition == null) {
            throw new RuntimeException("徽章不存在");
        }
        
        UserBadgePO userBadge = null;
        if (userId != null) {
            userBadge = userBadgeMapper.selectUserBadge(userId, badgeId);
        }
        
        BadgeDto badgeDto = new BadgeDto();
        badgeDto.setBadgeId(badgeDefinition.getBadgeId());
        badgeDto.setName(badgeDefinition.getName());
        badgeDto.setDescription(badgeDefinition.getDescription());
        badgeDto.setIconUrl(badgeDefinition.getIconUrl());
        badgeDto.setCategory(badgeDefinition.getCategory());
        badgeDto.setRequirement(badgeDefinition.getRequirement());
        
        if (userBadge != null) {
            badgeDto.setObtained(true);
            badgeDto.setEarnedAt(userBadge.getEarnedAt());
            badgeDto.setIsVisible(userBadge.getIsVisible());
        } else {
            badgeDto.setObtained(false);
            badgeDto.setIsVisible(false);
        }
        
        return badgeDto;
    }


    /**
     * 设置用户徽章显示状态
     * 
     * @param userId 用户ID
     * @param badgeId 徽章ID
     * @param isVisible 是否显示
     * @return 是否成功
     */
    public boolean setBadgeVisibility(Long userId, Long badgeId, Boolean isVisible) {
        log.info("设置用户徽章显示状态，userId: {}, badgeId: {}, isVisible: {}", userId, badgeId, isVisible);
        
        UserBadgePO userBadge = userBadgeMapper.selectUserBadge(userId, badgeId);
        if (userBadge == null) {
            throw new RuntimeException("用户未获得该徽章");
        }
        
        userBadge.setIsVisible(isVisible);
        int result = userBadgeMapper.updateById(userBadge);
        return result > 0;
    }

    /**
     * 统计用户徽章数量
     * 
     * @param userId 用户ID
     * @return 徽章数量
     */
    public Integer getUserBadgeCount(Long userId) {
        log.info("统计用户徽章数量，userId: {}", userId);
        
        return userBadgeMapper.countUserBadges(userId);
    }

    /**
     * 转换徽章定义PO为DTO
     * 
     * @param badgeDefinitions 徽章定义列表
     * @param userBadgeMap 用户徽章映射
     * @return 徽章DTO列表
     */
    private List<BadgeDto> convertToBadgeDtos(List<BadgeDefinitionPO> badgeDefinitions, Map<Long, UserBadgePO> userBadgeMap) {
        List<BadgeDto> badgeDtos = new ArrayList<>();
        
        for (BadgeDefinitionPO badgeDef : badgeDefinitions) {
            BadgeDto badgeDto = new BadgeDto();
            badgeDto.setBadgeId(badgeDef.getBadgeId());
            badgeDto.setName(badgeDef.getName());
            badgeDto.setDescription(badgeDef.getDescription());
            badgeDto.setIconUrl(badgeDef.getIconUrl());
            badgeDto.setCategory(badgeDef.getCategory());
            badgeDto.setRequirement(badgeDef.getRequirement());
            
            if (userBadgeMap != null) {
                UserBadgePO userBadge = userBadgeMap.get(badgeDef.getBadgeId());
                if (userBadge != null) {
                    badgeDto.setObtained(true);
                    badgeDto.setEarnedAt(userBadge.getEarnedAt());
                    badgeDto.setIsVisible(userBadge.getIsVisible());
                } else {
                    badgeDto.setObtained(false);
                    badgeDto.setIsVisible(false);
                }
            } else {
                badgeDto.setObtained(false);
                badgeDto.setIsVisible(false);
            }
            
            badgeDtos.add(badgeDto);
        }
        
        return badgeDtos;
    }
}
